package com.hibase.core.mybatis.registrar;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.hibase.core.mybatis.constant.HibaseSqlMethod;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 自定义拼接修改idsql
 *
 * @author hufeng
 * @date 2019/03/26
 */
public class UpdateNullById extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        HibaseSqlMethod sqlMethod = HibaseSqlMethod.UPDATE_NULL_BY_ID;
        String additional = this.optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);
        // 修改不过滤逻辑删除字段
        String sql = String.format(sqlMethod.getSql(),
                tableInfo.getTableName(),
                sqlSet(tableInfo.isWithLogicDelete(),
                        false,
                        tableInfo,
                        false,
                        ENTITY, ENTITY_DOT),
                        tableInfo.getKeyColumn(),
                        ENTITY_DOT + tableInfo.getKeyProperty(),
                        additional);
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
    }

    protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias, final String prefix) {
        String sqlScript = this.getAllSqlSet(table,logic, prefix);
        if (judgeAliasNull) {
            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true);
        }

        if (ew) {
            sqlScript = sqlScript + "\n";
            sqlScript = sqlScript + SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam("ew.sqlSet"), String.format("%s != null or %s != null or %s == null or %s == null", "ew", "ew.sqlSet","ew","ew.sqlSet"), false);
        }

        sqlScript = SqlScriptUtils.convertSet(sqlScript);
        return sqlScript;
    }

    public String getAllSqlSet(TableInfo table,boolean ignoreLogicDelFiled, final String prefix) {
        String newPrefix = prefix == null ? "" : prefix;
        return (String)table.getFieldList().stream().filter((i) -> {
            if (!ignoreLogicDelFiled) {
                return true;
            } else {
                return !table.isWithLogicDelete() || !i.isLogicDelete();
            }
        }).map((i) -> {
            return i.getSqlSet(true,newPrefix);
        }).filter(Objects::nonNull).collect(Collectors.joining("\n"));
    }
}
